import os
import traceback
from datetime import datetime

from flask import Blueprint, jsonify, request

from app.server.ensemble_model import TemperatureForecaster

# 创建蓝图
train_ensemble_bp = Blueprint('ensemble_train', __name__)

@train_ensemble_bp.route('/train_ensemble', methods=['GET'])
def train_ensemble_model():

    try:
        # 获取参数，设置默认值
        target = request.args.get('target_col', default='guilin_max')
        horizon = int(request.args.get('horizon', default=7))

        # 验证预测天数范围
        if horizon <= 0 or horizon > 180:
            return jsonify({
                'status': 'error',
                'message': '预测天数必须在1到365天之间'
            }), 400

        # 初始化预测器
        forecaster = TemperatureForecaster(target_col=target)


        # 训练模型
        forecaster.train_models(horizon=horizon)

        return jsonify({
            'status': 'success',
            'message': f'成功训练{horizon}天的温度预测模型',
            'target_column': target,
            'horizon': horizon,
            'model_dir': forecaster.model_dir,
            'timestamp': datetime.now().strftime("%Y%m%d_%H%M%S")
        })

    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'训练过程中发生错误: {str(e)}',
            'traceback': traceback.format_exc()
        }), 500

@train_ensemble_bp.route('/train_ensemble_status', methods=['GET'])
def train_ensemble_status():

    try:
        target_col_filter = request.args.get('target_col', default='guilin_max')
        model_dir = os.path.join('app', 'saved_models', 'MultiDayEnsembleModel', 'next_train_ensemble')

        # 检查模型目录是否存在
        if not os.path.exists(model_dir):
            return jsonify({
                'status': f'not_trained_in_{model_dir}',
                'message': '尚未训练任何模型'
            })

        # 获取所有模型文件
        model_files = [f for f in os.listdir(model_dir) if f.endswith('.pkl')]

        if not model_files:
            return jsonify({
                'status': 'not_trained',
                'message': '模型目录存在但未包含任何训练好的模型'
            })

        # 处理模型文件信息
        models_info = []
        target_cols = set()
        horizons = set()

        for filename in model_files:
            try:
                # 使用更健壮的文件名解析方法
                # 文件名格式应为：guilin_temp_day_1.pkl
                parts = filename.split('.')[0].split('_')  # 先去掉.pkl再分割

                # 确保文件名格式正确
                if len(parts) >= 4 and parts[-2] == 'day':
                    target_col = '_'.join(parts[:-2])  # 处理可能含有下划线的目标列名
                    day = int(parts[-1])  # 最后一部分是day数字

                    # 按目标列筛选
                    if target_col_filter and target_col != target_col_filter:
                        continue

                    target_cols.add(target_col)
                    horizons.add(day)

                    models_info.append({
                        'target_column': target_col,
                        'day': day,
                        'file': filename,
                        'last_modified': datetime.fromtimestamp(
                            os.path.getmtime(os.path.join(model_dir, filename))
                        ).strftime('%Y-%m-%d %H:%M:%S')
                    })
            except (ValueError, IndexError) as e:
                print(f"跳过无效文件名格式: {filename}, 错误: {str(e)}")
                continue

        return jsonify({
            'status': 'success',
            'models': models_info,
            'available_targets': list(target_cols),
            'max_horizon': max(horizons) if horizons else 0,
            'model_count': len(model_files),
            'message': '成功获取模型状态信息'
        })

    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取模型状态时发生错误: {str(e)}'
        }), 500
